package com.twu.biblioteca;

import java.util.ArrayList;
import java.util.Scanner;

import static com.twu.biblioteca.Library.listAvailableTitles;
import static java.lang.System.out;


public class BibliotecaApp {

    protected Library publicLibrary;
    protected ArrayList<Customer> loggedInCustomers;

    public BibliotecaApp(){
        publicLibrary = new Library();
        loggedInCustomers = new ArrayList<Customer>();
    }

    private bibliotecaHelper helper = new bibliotecaHelper();

    public static void welcomeCustomer(){
       out.println("Welcome to Biblioteca!");
    }

    public static void menuOptionsBeforeLogIn(){
        out.println(" --------------------------");
        out.println("|Choose from options below:|");
        out.println("|--------------------------|");
        out.println("|List Books                |");
        out.println("|--------------------------|");
        out.println("|List Movies               |");
        out.println("|--------------------------|");
        out.println("|Log In                    |");
        out.println("|--------------------------|");
        out.println("|Quit                      |");
        out.println("|--------------------------|");
        out.println("");
    }

    private static void setUpBiblioteca(){
        welcomeCustomer();
        menuOptionsBeforeLogIn();
    }

    public static void menuOptions(){
        out.println(" --------------------------");
        out.println("|Choose from options below:|");
        out.println("|--------------------------|");
        out.println("|List Books                |");
        out.println("|--------------------------|");
        out.println("|List Movies               |");
        out.println("|--------------------------|");
        out.println("|Check-Out A Book          |");
        out.println("|--------------------------|");
        out.println("|Check-Out A Movie         |");
        out.println("|--------------------------|");
        out.println("|Return A Book             |");
        out.println("|--------------------------|");
        out.println("|Return A Movie            |");
        out.println("|--------------------------|");
        out.println("|My Details                |");
        out.println("|--------------------------|");
        out.println("|Checked Out Items         |");
        out.println("|--------------------------|");
        out.println("|Quit                      |");
        out.println("|--------------------------|");
        out.println("");
    }

    public void detectPreSignInChosenOption(Customer customer, String input) {
        if(input.equals("List Books")){
            showItemsAndOptions(customer, publicLibrary.availableBooks);
        }else if(input.equals("List Movies")){
            showItemsAndOptions(customer, publicLibrary.availableMovies);
        }else if(input.equals("Log In")){
            loginAndShowOptions(customer);
        }else if(input.equals("Quit")) {
            System.exit(0);
        }else{
            invalidOptionSelected(customer);
        }
    }

    public void login(Customer customer, String username, String password) {
        if(customer.libraryNumber().equals(username) && customer.password().equals(password)){
            loggedInCustomers.add(customer);
            out.println("You have successfully logged in!");
        }else{
            failedLogin(customer);
        }
    }

    public void loginWithDetails(Customer customer){
        System.out.println("Enter your username: ");
        Scanner scanner = new Scanner(System.in);
        String username = scanner.nextLine();
        System.out.println("Enter your password: ");
        String password = scanner.nextLine();
        login(customer, username, password);
    }

    private void failedLogin(Customer customer){
        out.println("Either your username or password is wrong");
        menuOptionsBeforeLogIn();
        detectPreSignInChosenOption(customer, getInput());
    }

    private void loginAndShowOptions(Customer customer){
        loginWithDetails(customer);
        if(loggedInCustomers.contains(customer)){
            showLoggedInMenuOptionAndGetInput(customer);
        }
    }

    private void showLoggedInMenuOptionAndGetInput(Customer customer){
        menuOptions();
        checkUserInput(customer, getInput());
    }

    public String getInput(){
        String userOption = helper.getUserInput("Type In Selected Option here:");
        return userOption;
    }

    public void checkUserInput(Customer customer, String input){
        if(input.equals("List Books")){
            showItemsAndOptions(customer, publicLibrary.availableBooks);
        }else if(input.equals("List Movies")){
            showItemsAndOptions(customer, publicLibrary.availableMovies);
        }else if(input.equals("Quit")) {
            System.exit(0);
        }else if(input.equals("Check-Out A Book")){
            checkBookOut(customer);
        }else if(input.equals("Check-Out A Movie")){
            checkMovieOut(customer);
        }else if(input.equals("Return A Book")){
            ReturnItem(customer, customer.booksInPossession, publicLibrary.availableBooks);
        }else if(input.equals("Return A Movie")){
            ReturnItem(customer, customer.moviesInPosession, publicLibrary.availableMovies);
        }else if(input.equals("My Details")){
            detailsOf(customer);
        }else if(input.equals("Checked Out Items")){
            listLocationsAndContinueBrowsing(customer);
        }else{
            invalidOptionSelected(customer);
        }
    }

    private void listLocationsAndContinueBrowsing(Customer customer){
        publicLibrary.locationOfItems();
        GetFurtherInstructions(customer);
    }

    private void checkMovieOut(Customer customer) {
        customer.checkOutItemFromTo(getItemNumber(), publicLibrary.availableMovies, customer.moviesInPosession, publicLibrary);
        GetFurtherInstructions(customer);
    }

    public void checkBookOut(Customer customer){
        customer.checkOutItemFromTo(getItemNumber(), publicLibrary.availableBooks, customer.booksInPossession, publicLibrary);
        GetFurtherInstructions(customer);
    }

    private <T extends Item> void showItemsAndOptions(Customer customer, ArrayList<T> listOfItems){
        for(int i = 0; i < listOfItems.size(); i++){
            out.println((i+1) + ". " + listAvailableTitles(listOfItems).get(i));
        }
        GetFurtherInstructions(customer);
    }

    private int getItemNumber(){
        String itemChoice = helper.getUserInput("Item number you wish to check out:");
        return Integer.parseInt(itemChoice);
    }

    private void GetFurtherInstructions(Customer customer){
        menuOptions();
        checkUserInput(customer, getInput());
    }

    private void invalidOptionSelected(Customer customer){
        System.out.println("Select a valid option!");
        checkUserInput(customer, getInput());
    }

    private <T extends Item> void ReturnItem(Customer customer, ArrayList<T> fromItemCollection, ArrayList<T> toItemCollection){
        if(fromItemCollection.size()>0){
            successfullyReturnItem(customer, fromItemCollection, toItemCollection);
        }else{
            unsuccessfullyReturn(customer, fromItemCollection, toItemCollection);
        }
    }

    private <T extends Item> void successfullyReturnItem(Customer customer, ArrayList<T> fromItemCollection, ArrayList<T> toItemCollection){
        itemsInPossession(customer, fromItemCollection);
        obtainInputAndReturnItem(customer, fromItemCollection, toItemCollection);
        GetFurtherInstructions(customer);
    }

    private static <T extends Item> void itemsInPossession(Customer customer, ArrayList<T> itemsInPosession){
        System.out.println("Movies currently in possession:");
        customer.currentlyHolding(itemsInPosession);
    }

    private <T extends Item> void unsuccessfullyReturn(Customer customer, ArrayList<T> fromItemCollection, ArrayList<T> toItemCollection){
        System.out.println("You have no movies to return");
        GetFurtherInstructions(customer);
    }

    private <T extends Item> void obtainInputAndReturnItem(Customer customer, ArrayList<T> fromItemCollection, ArrayList<T> toItemCollection){
        String bookToReturn = helper.getUserInput("Type in the item's number to return the book:");
        customer.returnItem(Integer.parseInt(bookToReturn), fromItemCollection, toItemCollection, publicLibrary);
    }

    public static void main(String[] args) {

        BibliotecaApp libraryApp = new BibliotecaApp();
        Customer customer = new Customer("Michael", "michaelbottjer@hotmail.com", "07788436628");
        out.println(customer.libraryNumber());
        setUpBiblioteca();
        libraryApp.detectPreSignInChosenOption(customer, libraryApp.getInput());

    }

    public void detailsOf(Customer customer) {
        for(String detail : customer.details.values()){
            out.println(detail);
        }
    }
}
